home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / ada / gwuada_4.zip / INT21.ASM < prev    next >
Assembly Source File  |  1990-07-25  |  6KB  |  273 lines

  1.     name    int21
  2. _text    segment    byte public 'code'
  3. dgroup    group    _data,_bss
  4.     assume    cs:_text,ds:dgroup
  5. _text    ends
  6. _data    segment word public 'data'
  7. _d@    label    byte
  8. _data    ends
  9. _bss    segment word public 'bss'
  10. _b@    label    byte
  11. _bss    ends
  12.  
  13. ;
  14. ; I switch to my own stack when handling an int 21 request on behalf
  15. ; of a process. This is done because the amount of stack available to
  16. ; the calling process is not known. The flag "onintstack" indicates
  17. ; whether this special stack is currently in use so that we do not
  18. ; inadvertantly try to use it again. If an int 21 call is made while
  19. ; this stack is in use (as can occur for instance when we are flushing
  20. ; a buffer to disk, or calling ioctl to find out whether the current
  21. ; handle refers to the console), we do not call the C function
  22. ; "int21handler", but rather chain to DOS immediately.
  23. ;
  24. _bss    segment word public 'bss'
  25.     db    512 dup (?)
  26. intstack    label    byte
  27. _bss    ends
  28.  
  29. _text      segment byte public 'code'
  30.     public    _grab21, _rstr21, _getpsp, _setpsp, _getdosflag, _callDOS
  31.     extrn    _int21handler:near
  32.  
  33. savesp        dw    ?    ; saved ss:sp of calling process
  34. savess        dw    ?
  35. onintstack    dw    ?
  36.  
  37. ;
  38. ; psp = getpsp(void)
  39. ;
  40. _getpsp proc near
  41.     mov    ah, 51h
  42.     int    21h
  43.     mov    ax, bx
  44.     ret
  45. _getpsp endp
  46.  
  47. ;
  48. ; void setpsp(psp)
  49. ;
  50. ; This function uses undocumented DOS function 50h
  51. ;
  52. _setpsp proc near
  53.     push    bp
  54.     mov    bp, sp
  55.     mov    bx, [bp+4]
  56.     mov    ah, 50h
  57.     int    21h
  58.     pop    bp
  59.     ret
  60. _setpsp endp
  61.  
  62. ;
  63. ; char far *dosflag = getdosflag(void);
  64. ;
  65. ; Returns a pointer to the "indos" flag. This is used to prevent
  66. ; any attempt to re-enter DOS.
  67. ;
  68. _getdosflag proc near
  69.     mov    ah,34h
  70.     int    21h
  71.     mov    ax, bx
  72.     mov    dx, es
  73.     ret
  74. _getdosflag endp
  75.  
  76. ;
  77. ; int grab21(void)
  78. ;
  79. ; Intercept DOS function calls by installing our own
  80. ; int 21 handler. Zero is returned if the current int 21
  81. ; handler has the same offset as the one being installed.
  82. ; This is used as a quick check to see if script
  83. ; is already active. It is far from a foolproof check,
  84. ; for instance it is possible that the DOS interrupt
  85. ; handler has the same offset as our own handler in which
  86. ; case this function would indicate that script was already
  87. ; active when in fact it was not. The probability is reasonably
  88. ; small that this won't occur.
  89. ;
  90. _grab21 proc near
  91.     mov    ax, 3521h            ; save current int 21 handler
  92.     int    21h
  93.     mov    word ptr cs:oldvct21, bx
  94.     mov    word ptr cs:oldvct21+2, es
  95.     mov    dx, offset int21        ; set up our int 21 handler
  96.     cmp    bx, dx
  97.     je    nogo
  98.     mov    ax, 2521h
  99.     int    21h
  100.     mov    cs:onintstack,0
  101.     mov    ax,1
  102.     ret
  103. nogo:
  104.     mov    ax,0
  105.     ret
  106. _grab21 endp
  107.  
  108. ;
  109. ; rstr21()
  110. ;
  111. ; Repair the damage done above before exiting.
  112. ;
  113. _rstr21 proc near
  114.     mov    cs:onintstack,1
  115.     push    ds
  116.     lds    dx, dword ptr cs:oldvct21
  117.     mov    ax, 2521h
  118.     int    21h
  119.     pop    ds
  120.     ret
  121. _rstr21 endp
  122.  
  123. ;
  124. ; The int 21 first level handler.
  125. ; This function sets up a stack, pushes the processor registers
  126. ; on this stack, and then calls C. In order that the C handler
  127. ; can make DOS calls without recursing, the flag "onintstack"
  128. ; is set. If the following ISR is called when this flag is set,
  129. ; it will not call the C handler again, but instead will chain
  130. ; immediately to DOS
  131. ;
  132. int21    proc    far
  133.     cmp    cs:onintstack, 0
  134.     jne    chain
  135.     mov    cs:onintstack, 1
  136.     mov    word ptr cs:savesp, sp        ; switch stacks
  137.     mov    word ptr cs:savess, ss
  138.     push    cs
  139.     pop    ss
  140.     mov    sp, offset dgroup:intstack
  141.     sti
  142.     cld
  143. ;
  144.     push    es                ; Save regs on the new stack.
  145.     push    ds                ; The C function "int21hander"
  146.     push    dx                ; expects the registers
  147.     push    cx                ; in this order.
  148.     push    bx                ; They must look like a
  149.     push    ax                ; "union MYFRAME"
  150.  
  151.     push    cs
  152.     pop    ds
  153.  
  154.     call    near ptr _int21handler
  155.     mov    ah,al
  156.     sahf
  157.     pop    ax
  158.     pop    bx
  159.     pop    cx
  160.     pop    dx
  161.     pop    ds
  162.     pop    es
  163. ;
  164.     mov    cs:onintstack, 0
  165.     mov    ss, word ptr cs:savess ; Restore the original stack
  166.     mov    sp, word ptr cs:savesp
  167.  
  168.     je    chain        ; Nothing between the sahf above, and here
  169.                 ; is allowed to affect the flags.
  170.     ret    2        ; Carry flag still set from sahf above.
  171. chain:
  172.     db    0EAh    ; opcode for FAR JUMP
  173. oldvct21    dd    ?
  174. int21    endp
  175.  
  176. ;
  177. ; flags = callDOS(regp)
  178. ; union MYFRAME *regp;
  179. ;
  180. ; This function loads the registers from "regp", executes an int 21
  181. ; and then copies the modified registers back into "regp"
  182. ; The processor flags are returned as the value of the function
  183. ;
  184. ; This function is currently used to read console input on behalf
  185. ; of a process and is called while the special stack is in use.
  186. ; This means that "onintstack" is set. A problem arises if the
  187. ; user types ^C in response to this input request. In this case,
  188. ; the calling process is aborted by DOS and never returns to this
  189. ; procedure. This means that we never get a chance to clear
  190. ; "onintstack". The effects of this are that no further output
  191. ; will be written to the output file. A possible solution may
  192. ; be to chain to the termination vector (int 22h), but this would
  193. ; have to done every time "callDOS" is called and not just once
  194. ; when script starts up, because DOS fiddles with this vector
  195. ; whenever a new process is created, or an old one destroyed.
  196. ;
  197. _callDOS proc near
  198.     push    bp
  199.     mov    bp,sp
  200.     mov    bx,[bp+4]
  201.  
  202.     mov    es, [bx+10]
  203.     mov    ax,[bx+8]
  204.     push    ax
  205.     mov    dx, [bx+6]
  206.     mov    cx, [bx+4]
  207.     mov    ax, [bx+0]
  208.     mov    bx, [bx+2]
  209.     pop    ds
  210.  
  211.     pushf                ; Fake interrupt
  212.     call oldvct21
  213.     pushf                ; Preserve flags from DOS
  214.  
  215.     push    ds
  216.     push    cs
  217.     pop    ds
  218.     push    bx
  219.     mov    bx,[bp+4]
  220.     mov    [bx+0],ax
  221.     pop    [bx+2]
  222.     mov    [bx+4],cx
  223.     mov    [bx+6],dx
  224.     pop    [bx+8]
  225.     mov    [bx+10],es
  226.  
  227.     pop    ax            ; Return the flags from the DOS call
  228.     pop    bp
  229.     ret
  230. _callDOS endp
  231.  
  232. ;
  233. ; void _Getdate(struct date *)
  234. ;
  235. public _Getdate
  236. _Getdate    proc near
  237.     push    bp
  238.     mov    bp,sp
  239.     mov    ah, 2Ah
  240.     int    21h
  241.     mov    bx,[bp+4]
  242.     mov    [bx],cx
  243.     mov    [bx+2],dx
  244.     mov    [bx+4],al
  245.     pop    bp
  246.     ret
  247. _Getdate    endp
  248.  
  249. ;
  250. ; void _Gettime(struct time *)
  251. ;
  252. public _Gettime
  253. _Gettime    proc near
  254.     push    bp
  255.     mov    bp,sp
  256.     mov    ah, 2Ch
  257.     int    21h
  258.     mov    bx,[bp+4]
  259.     mov    [bx],dx
  260.     mov    [bx+2],cx
  261.     pop    bp
  262.     ret
  263. _Gettime    endp
  264.  
  265. _text    ends
  266.  
  267.  
  268. _data    segment word public 'data'
  269. _s@    label byte
  270. _data    ends
  271.  
  272.     end
  273.